from pynput import keyboard, mouse
import pymysql
import ctypes
import re


# # 数据库连接函数
# def excute_sql(sqls:list):
#     db = pymysql.connect(   
#         host='localhost',
#         user='root',
#         password='root',
#         database='keymousedb', 
#         charset='utf8mb4'
#         )
#     cursor = db.cursor()
#     for sql in sqls:
#         try:
#             cursor.execute(sql)
#             db.commit()
#         except:
#             db.rollback()
#     db.close()

lower_to_upper = {
    'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D', 'e': 'E', 'f': 'F', 'g': 'G', 'h': 'H', 'i': 'I',
    'j': 'J', 'k': 'K', 'l': 'L','m': 'M', 'n': 'N', 'o': 'O', 'p': 'P', 'q': 'Q', 'r': 'R',
  's': 'S', 't': 'T', 'u': 'U', 'v': 'V', 'w': 'W', 'x': 'X', 'y': 'Y', 'z': 'Z'
}
shift_char_mapping = {
    '1': '!', '2': '@', '3': '#', '4': '$', '5': '%', '6': '^', '7': '&', '8': '*', '9': '(',
    '0': ')', '-': '_', '=': '+', '[': '{', ']': '}', '\\': '|', ';': ':', "'": '"', ',': '<',
    '.': '>', '/': '?'
}
# 用于转换大小写
press = set()
# 按键次数字典
keydict = dict()
# 鼠标点击字典
mousedict = {
    "left": 0,
    "middle": 0,
    "right": 0
}

def is_uppercase():
    # 只适用于windows检测大写状态
    hllDll = ctypes.WinDLL("User32.dll")
    VK_CAPITAL = 0x14
    VK_SHIFT_LEFT = 0x10
    VK_SHIFT_RIGHT = 0xA0
    caps_lock_state = hllDll.GetKeyState(VK_CAPITAL) & 1
    left_shift_state = hllDll.GetKeyState(VK_SHIFT_LEFT) & 0x8000
    right_shift_state = hllDll.GetKeyState(VK_SHIFT_RIGHT) & 0x8000
    return caps_lock_state or left_shift_state or right_shift_state

def transelate(char):
    global press
    # 11 shift 在 caps_lock在 字母返回 if re.match(r"a-z")，符号数字转换shift_char_mapping.get(char,char)
    if "shift" in press and "caps_lock" in press:
        if bool(re.match(r"a-z",char)):
            return char
        else:
            return shift_char_mapping.get(char,char)
    # 10 shift 在 caps_lock不在 返回{**lower_to_upper, **shift_char_mapping}.get(char,char)
    elif "shift" in press and "caps_lock" not in press :
        return {**lower_to_upper, **shift_char_mapping}.get(char,char)
    # 01 shift 不在 caps_lock在 返回 lower_to_upper.get(char,char)
    elif "shift" not in press and "caps_lock" in press:
        return lower_to_upper.get(char,char)
    # 00 shift 不在 caps_lock不在 返回char
    else:
        return char

def on_press(key):
    if hasattr(key, 'name'):
        if key.name == "shift" and "shift" not in press:
            press.add("shift")
        

# 键盘监听事件
def on_release(key):
    # 对按键进行加1
    if hasattr(key, 'char'): 
        char = transelate(key.char)
        if char not in keydict.keys():
            keydict[char] = 1
        else:
            keydict[char] += 1
    else:
        if key.name == "caps_lock" and "caps_lock" not in press :
            press.add("caps_lock")
            # print("caps_lock打开",press)
        elif key.name == "caps_lock" and "caps_lock" in press:
            # 再次按下大写字母关闭caps_lock
            press.remove("caps_lock")
            # print("caps_lock关闭",press)
        # 如果char 是shift 或 caps_lock 返回char 并删除press中的shift 或 caps_lock
        if key.name == "shift" and "shift" in press:
            press.remove(key.name)
        if key.name not in keydict.keys():
            keydict[key.name] = 1
        else:
            keydict[key.name] += 1
    print("键盘点击",keydict)


# 鼠标点击
def on_click(x, y, key, pressed):
    # 对按键进行加1
    if key.name not in mousedict.keys():
        mousedict[key.name] = 1
    else:
        mousedict[key.name] += 1
    # print("鼠标点击位置",x,y,key,pressed)
    print("鼠标点击",mousedict)
# 鼠标滚动算到
def on_scroll(x, y, dx, dy):
    # if dy > 0:
    #     print("鼠标滚轮向上滚动")
    # elif dy < 0:
    #     print("鼠标滚轮向下滚动")
    # else:
    #     print("鼠标未滚动")
    # print("鼠标点击结合",mousedict)
    mousedict["middle"] += 1
    

def main(*args, **kwargs):
    global press
    # 检测大写状态
    if is_uppercase():
        press.add("caps_lock")
    print("初始化",press)
    key = keyboard.Listener(on_release=on_release,on_press=on_press)
    mosue = mouse.Listener(on_click=on_click, on_scroll=on_scroll)
    mosue.start()
    key.start()
    if  kwargs.get("join",False):
        # 第一个位置参数给个true 主动阻塞一下
        key.join()
        mosue.join()

def get_count(*args,**kwargs):
    return keydict,mousedict

def clear_count(*args,**kwargs):
    keydict.clear()
    mousedict['left'] = 0
    mousedict['middle'] = 0
    mousedict['right'] = 0
      

if __name__ == "__main__":
    import time
    main(join=True)
    # 测试清空接口
    time.sleep(4)
    print(get_count())
    clear_count()
    print(get_count())
    
